#include <iostream>

#include <functional>

#include <nemesis.h>

#include <nemesis.app.Application.h>

class Sort : public app::Application {
public:
   Sort ();
   
   void initialize () throw (RuntimeException);
   
private:
   void  run () throw (RuntimeException);      
};

using namespace std;

int main (int argc, const char** argv)
{
   CommandLine& commandLine (CommandLine::instanciate ());
   Sort test;

   try {
      commandLine.initialize (argv, argc);
      commandLine.verify ();

      Logger::setLevel (Logger::Debug); 
      Logger::initialize ("recycler", new TraceWriter ("file.trace", 2048000));
 
      test.start ();
   }
   catch (Exception& ex) {
      cout << ex.asString () << endl;
   }
   
   return 0;
}

Sort::Sort () : 
   app::Application ("recycler", "Comprobacion del nemesis::Recycler<T>", "1.0") 
{
}

void Sort::initialize () 
   throw (RuntimeException)
{
}

struct Accesor {
   static int value (int* i) throw () { return *i; }
   static int value (const int* i) throw () { return *i; }
};

void print_const (const Recycler<int>& numbers)
{
   string msg;

   const int* c;
   for (Recycler <int>::const_iterator ii = numbers.begin (), maxii = numbers.end (); ii != maxii; ii ++) {
      c = Recycler <int>::data (ii);
      msg = nemesis::functions::asString ("Number 3 (p=0x%x): %d", c, *c);
      Logger::debug (msg, FILE_LOCATION);
   }
}

void Sort::run () 
   throw (RuntimeException)
{
   static const int N = 10;

   Recycler <int> numbers;
   int* p;
   int i;
   string msg;

   for (i = 0; i < N; i ++) {
      p = numbers.create ();
      *p = i;
   }

   for (Recycler <int>::iterator ii = numbers.begin (), maxii = numbers.end (); ii != maxii; ii ++) {
      p = Recycler <int>::data (ii);
      LOGDEBUG (
         msg = nemesis::functions::asString ("Number 1 (p=0x%x): %d", p, *p);
         Logger::debug (msg, FILE_LOCATION);
      );
   }
      
   while (numbers.size () > 2) {
      i = rand () % N;
      
      for (Recycler <int>::iterator ii = numbers.begin (), maxii = numbers.end (); ii != maxii; ii ++) {
         p = Recycler <int>::data (ii);
         if (i == *p) {
            LOGDEBUG (
               msg = nemesis::functions::asString ("Release Number 1 (p=0x%x): %d", p, *p);
               Logger::debug (msg, FILE_LOCATION);
            );
            numbers.release (ii);
            break;
         }
      }
   }
      
   for (i = 0; i < N; i ++) {
      p = numbers.create ();
      *p = i * 1000;
   }
   for (Recycler <int>::iterator ii = numbers.begin (), maxii = numbers.end (); ii != maxii; ii ++) {
      p = Recycler <int>::data (ii);
      LOGDEBUG (
         msg = nemesis::functions::asString ("Number 2 (p=0x%x): %d", p, *p);
         Logger::debug (msg, FILE_LOCATION);
      );
   }

   numbers.clear ();
   for (i = 0; i < N; i ++) {
      p = numbers.create ();
      *p = i * 2000;
   }

   print_const (numbers);
}


